﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;


namespace Kernelx.Contexts.Configuration
{
    using Core;
    using Defaults;
    using AspNetCoreImpls;
    using Extensions;

    /// <summary>
    /// 
    /// </summary>
    public static class AspNetCoreContextsExtensions
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static IServiceCollection AddWorkloadStartupContext(this IServiceCollection services, Action<AspNetCoreWorkloadContextOptions> action)
        {
            var options = new AspNetCoreWorkloadContextOptions(services);
            action(options);
            return services;
        }



        private static Func<IWebHostEnvironment, WorkloadEnvironment> _getWorkloadEnvironment;

        /// <summary> 
        /// 注册<see cref="StartupWorkloadEnvironment"/>的实例 
        /// </summary>
        /// <typeparam name="TEnvironment"></typeparam>
        /// <param name="getWorkloadEnvironment"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static WorkloadContextOptions RegisterWorkloadEnvironment<TEnvironment>(this WorkloadContextOptions ctxOpts, Func<IWebHostEnvironment, TEnvironment> getWorkloadEnvironment)
            where TEnvironment : WorkloadEnvironment, new()
        {
            _getWorkloadEnvironment = getWorkloadEnvironment ?? throw new ArgumentNullException(nameof(getWorkloadEnvironment));

            var envinment = new TEnvironment();
            ctxOpts.Services.AddSingleton(envinment);
            ctxOpts.Services.AddSingleton<WorkloadEnvironment>(envinment);
            return ctxOpts;
        }
         

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="getCurrentUser"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseWorkloadStartupContext(this IApplicationBuilder app, Func<HttpContext,ICurrentUser> getCurrentUser)
        {
            var serviceProvider = app.ApplicationServices;
            var env = _getWorkloadEnvironment(serviceProvider.GetService<IWebHostEnvironment>());
            env?.CopyTo(serviceProvider.GetService(env.GetType()), true);
             
            return app.Use(next =>
            {
                return new RequestDelegate(async context =>
                {
                    context.Request.EnableBuffering();
                    (WorkloadStartupContext.Current as NetCoreWorkloadContext).SetStartupMessage(context.RequestServices, context, getCurrentUser); 
                    await next.Invoke(context);
                });
            });
        }

        /// <summary>
        ///  用于程序启动时构建执行上下文
        /// </summary>
        /// <param name="app"></param>
        /// <param name="backWorker"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static IBackWorkloadScope CreateBackWorkloadScope(this IApplicationBuilder app, ICurrentUser backWorker)
        {
            var scope = app.ApplicationServices.CreateScope();
            var ctx = WorkloadStartupContext.Current as NetCoreWorkloadContext;
            ctx.SetStartupMessage(scope.ServiceProvider, null, _ => backWorker);
            return ctx;
        }

    }
}
